1 Introduction - the input data

In this session of GeDi you used the following data:

library("GeDi")
if(is.null(reactive_values$genesets)){
  cat("It seems like you did not provide data in this session.")
}else{
  DT::datatable(reactive_values$genesets, caption = "The input genesets")
}

From your initial input data, you have filtered the following genesets

if(length(reactive_values$filtered_genesets) > 0){
  DT::datatable(reactive_values$filtered_genesets, caption = "The filtered genesets")
}else{
  cat("It seems like you didn't filter genesets from the input data.")
}

Potentially you specified the species of your data and downloaded a Protein-Protein-Interaction (PPI) matrix.

if(is.null(input$species) || input$species == ""){
  cat("It seems like you didn't specify the species of your data.")
  
}else{
 cat("You specified the species of your data as ", input$species, sep = "")
}
## You specified the species of your data as Mus musculus
if(!is.null(reactive_values$ppi)){
  DT::datatable(reactive_values$ppi, caption = "The downloaded PPI")
}else{
  cat("It seems like you did not download a PPI matrix.")
}

1.1 Parameter settings

For some of the calculations and visualizations of the app, the selected parameters are important and crucial for the results. This is the current state of the individual parameters.

cat("Your parameters of the Distance Scores panel")
## Your parameters of the Distance Scores panel
scores <- names(reactive_values$scores)

if(length(scores) > 0){
  scoring <- paste(scores, collapse = "\n") 
  cat(paste("You have calculated distance scores of your data using the follow metrics: \n",
            scoring, sep = ""))
  cat(paste("\nFor the clustering method in the dendrogram, you have selected ", input$cluster_method_dendro, ".", sep = ""))
  cat(paste("\nAnd for threshold for the Scoring Network was set to ", input$similarityScores, ".",   sep = ""))
}else{
  cat("It seems like you did not specify a Scoring method and did not score your data.")
}
## You have calculated distance scores of your data using the follow metrics: 
## pMM
## GO Distance
## For the clustering method in the dendrogram, you have selected average.
## And for threshold for the Scoring Network was set to 0.3.
cat("Your parameters of the Clustering Graph panel")
## Your parameters of the Clustering Graph panel
string <- paste("You have selected ", input$select_clustering, " as clustering method. \n", sep = "")
if(is.null(input$select_clustering)){
  string <- ("It seems like you did not cluster your data in this session")
}else if(input$select_clustering == "Louvain"){
  string <- paste(string, "The threshold you selected for the Louvain clustering was set to ", input$louvain_threshold , ".", sep = "")
}else if (input$select_clustering == "Markov"){
  string <- paste(string, "The threshold you selected for the Markov clustering was set to ", input$markov_threshold , ".",  sep = "")
}else{
  string <- paste("The similarity Threshold was set to ", input$simThreshold, ".\nThe membership Threshold was set to ", input$memThreshold, ". \nThe clustering Threshold was set to ", input$clustThreshold, ".", sep = "")
}
cat(string)
## The similarity Threshold was set to 0.5.
## The membership Threshold was set to 0.5. 
## The clustering Threshold was set to 0.5.

2 A quick overview on the scoring results

This section shows the visualizations of the Scoring panel.

if(length(reactive_values$scores) == 0){
  cat("It seems like you do not have distance scores calculated for your data.")
}else{
  if(input$plots_distance_score == ""){
    scores <- reactive_values$scores[[1]] 
    cat(paste("Your plots will be generated on the distance scores calculated with ", names(reactive_values$scores)[[1]], sep = ""))
  }else{
    scores <- reactive_values$scores[[input$plots_distance_score]] 
    cat(paste("Your plots will be generated on the distance scores calculated with ", input$plots_distance_score, sep = ""))
  }
  scoring_heatmap <- distanceHeatmap(scores)
  scoring_heatmap
}
## Your plots will be generated on the distance scores calculated with GO Distance

if(!length(reactive_values$scores) == 0) {
  dendro <-
    distanceDendro(scores, input$cluster_method_dendro)
  dendro
} else{
  cat("It seems like you do not have distance scores calculated for your data.")
}

library("visNetwork")
if(!length(reactive_values$scores) == 0){
  graph <- reactive_values$scores_graph()

visNetwork::visIgraph(graph) %>%
          visNodes(color = list(
            background = "#0092AC",
            highlight = "gold",
            hover = "gold"
          )) %>%
          visEdges(color = list(
            background = "#0092AC",
            highlight = "gold",
            hover = "gold"
          )) %>%
          visOptions(
            highlightNearest = list(
              enabled = TRUE,
              degree = 1,
              hover = TRUE
            ),
            nodesIdSelection = TRUE
          ) %>%
          visExport(
            name = "distance_scores_network",
            type = "png",
            label = "Save Distance Scores graph"
          )
}else{
    cat("It seems like you do not have distance scores calculated for your data.")
}

3 A quick overview of the clustering results

if(!is.null(reactive_values$cluster)){
  graph <- reactive_values$cluster_graph()

visNetwork::visIgraph(graph) %>%
          visOptions(
            highlightNearest = list(
              enabled = TRUE,
              degree = 1,
              hover = TRUE
            ),
            nodesIdSelection = TRUE,
            selectedBy = list(variable = "cluster", multiple = TRUE)
          ) %>%
          visExport(
            name = "cluster_network",
            type = "png",
            label = "Save Cluster graph"
          )
} else{
  cat("It seems like you did not cluster your data in this session")
}
if(!is.null(reactive_values$cluster)){
  graph <- reactive_values$bipartite_graph()

visNetwork::visIgraph(graph) %>%
        visIgraphLayout(layout = "layout_as_bipartite") %>%
        visOptions(
          highlightNearest = list(
            enabled = TRUE,
            degree = 1,
            hover = TRUE
          ),
          nodesIdSelection = TRUE
        ) %>%
        visExport(
          name = "bipartite_network",
          type = "png",
          label = "Save Cluster-Geneset bipartite graph"
        )
}else{
  cat("It seems like you did not cluster your data in this session")
}

4 Highlighting your bookmarked genesets and clusters

If you have bookmarked any genesets or clusters, they will be displayed here.

if(!(nrow(reactive_values$bookmarked_genesets) == 0)){
  cat("Here is a data table of your bookmarked genesets. \n")
  DT::datatable(reactive_values$bookmarked_genesets, rownames = F)
}else{
  cat("You have not bookmarked any genesets to be displayed here.")
}
## Here is a data table of your bookmarked genesets.
if(!(nrow(reactive_values$bookmarked_cluster) == 0)){
  for(i in 1:nrow(reactive_values$bookmarked_cluster)){
    cluster <- reactive_values$bookmarked_cluster[i, ]
    cluster_nb <- cluster[["Cluster"]]
    cat(paste("Now, we will have a look at ", cluster_nb, " which has the following genesets as members: ", cluster["Cluster_Members"], ".\n", sep = ""))
    cat(paste("The clusters are involved in the following biological processes: ", cluster["Cluster_Member_Description"], ".\n", sep = ""))

    cluster_nb <- as.numeric(unlist(strsplit(
        cluster_nb, split = ' ', fixed = TRUE
      ))[2])
    
    genesets <- reactive_values$cluster[[cluster_nb]]
    genesets_df <- reactive_values$genesets[genesets, ]
    cat(paste("Showing the Enrichment Wordcloud for cluster ", cluster_nb, "\n\n", sep = ""))
    e <- enrichmentWordcloud(genesets_df)
    print(e)
      
  }
}else{
  cat("You have not bookmarked any clusters to be displayed here.")
}
## Now, we will have a look at Cluster 20 which has the following genesets as members: GO:0033077, GO:0046632, GO:0045063, GO:0045580, GO:0072540, GO:0001779, GO:0002520, GO:0045579, GO:0043368, GO:0002763, GO:0035710, GO:0043371, GO:0045619, GO:0002335, GO:0002293.
## The clusters are involved in the following biological processes: T cell differentiation in thymus, alpha-beta T cell differentiation, T-helper 1 cell differentiation, regulation of T cell differentiation, T-helper 17 cell lineage commitment, natural killer cell differentiation, immune system development, positive regulation of B cell differentiation, positive T cell selection, positive regulation of myeloid leukocyte differentiation, CD4-positive, alpha-beta T cell activation, negative regulation of CD4-positive, alpha-beta T cell differentiation, regulation of lymphocyte differentiation, mature B cell differentiation, alpha-beta T cell differentiation involved in immune response.
## Showing the Enrichment Wordcloud for cluster 20
## 
## Now, we will have a look at Cluster 27 which has the following genesets as members: GO:0007265, GO:0008630, GO:0038061, GO:0019221, GO:0001836, GO:0097192, GO:0008625, GO:0097193, GO:2001244, GO:1902041, GO:2001237, GO:0043122, GO:0051896, GO:0070059.
## The clusters are involved in the following biological processes: Ras protein signal transduction, intrinsic apoptotic signaling pathway in response to DNA damage, non-canonical NF-kappaB signal transduction, cytokine-mediated signaling pathway, release of cytochrome c from mitochondria, extrinsic apoptotic signaling pathway in absence of ligand, extrinsic apoptotic signaling pathway via death domain receptors, intrinsic apoptotic signaling pathway, positive regulation of intrinsic apoptotic signaling pathway, regulation of extrinsic apoptotic signaling pathway via death domain receptors, negative regulation of extrinsic apoptotic signaling pathway, regulation of canonical NF-kappaB signal transduction, regulation of phosphatidylinositol 3-kinase/protein kinase B signal transduction, intrinsic apoptotic signaling pathway in response to endoplasmic reticulum stress.
## Showing the Enrichment Wordcloud for cluster 27

5 About this report

If you use this report in your scientific work, please cite GeDi:

utils::citation("GeDi")

Session info

This is the output of the sessionInfo() command, reported for improving the reproducibility of the analysis.

utils::sessionInfo()
## R Under development (unstable) (2024-03-12 r86109)
## Platform: x86_64-apple-darwin20
## Running under: macOS Ventura 13.2.1
## 
## Matrix products: default
## BLAS:   /System/Library/Frameworks/Accelerate.framework/Versions/A/Frameworks/vecLib.framework/Versions/A/libBLAS.dylib 
## LAPACK: /Library/Frameworks/R.framework/Versions/4.4-x86_64/Resources/lib/libRlapack.dylib;  LAPACK version 3.12.0
## 
## locale:
## [1] en_US.UTF-8/en_US.UTF-8/en_US.UTF-8/C/en_US.UTF-8/en_US.UTF-8
## 
## time zone: Europe/Berlin
## tzcode source: internal
## 
## attached base packages:
## [1] stats4    stats     graphics  grDevices utils     datasets  methods  
## [8] base     
## 
## other attached packages:
##  [1] visNetwork_2.1.2            shiny_1.9.1                
##  [3] GeDi_1.1.2                  ggdendro_0.2.0             
##  [5] testthat_3.2.1.1            devtools_2.4.5             
##  [7] usethis_3.0.0               org.Mm.eg.db_3.19.1        
##  [9] readxl_1.4.3                dplyr_1.1.4                
## [11] apeglm_1.26.1               GeneTonic_2.8.0            
## [13] ideal_1.99.0                pcaExplorer_2.99.1         
## [15] topGO_2.56.0                SparseM_1.84-2             
## [17] GO.db_3.19.1                AnnotationDbi_1.66.0       
## [19] graph_1.82.0                DESeq2_1.44.0              
## [21] SummarizedExperiment_1.34.0 MatrixGenerics_1.16.0      
## [23] matrixStats_1.4.1           GenomicRanges_1.56.2       
## [25] GenomeInfoDb_1.40.1         IRanges_2.38.1             
## [27] S4Vectors_0.42.1            knitr_1.48                 
## [29] Biobase_2.64.0              BiocGenerics_0.50.0        
## 
## loaded via a namespace (and not attached):
##   [1] R.methodsS3_1.8.2        GSEABase_1.66.0          progress_1.2.3          
##   [4] urlchecker_1.0.1         wordcloud2_0.2.1         DT_0.33                 
##   [7] Biostrings_2.72.1        vctrs_0.6.5              digest_0.6.37           
##  [10] png_0.1-8                shape_1.4.6.1            shinyBS_0.61.1          
##  [13] registry_0.5-1           ggrepel_0.9.6            magick_2.8.5            
##  [16] MASS_7.3-61              reshape2_1.4.4           httpuv_1.6.15           
##  [19] foreach_1.5.2            qvalue_2.36.0            withr_3.0.1             
##  [22] xfun_0.48                ggfun_0.1.6              ellipsis_0.3.2          
##  [25] survival_3.7-0           commonmark_1.9.2         memoise_2.0.1           
##  [28] clusterProfiler_4.12.6   gson_0.1.0               profvis_0.4.0           
##  [31] BiasedUrn_2.0.12         systemfonts_1.1.0        ragg_1.3.3              
##  [34] tidytree_0.4.6           GlobalOptions_0.1.2      gtools_3.9.5            
##  [37] R.oo_1.26.0              prettyunits_1.2.0        KEGGREST_1.44.1         
##  [40] promises_1.3.0           httr_1.4.7               restfulr_0.0.15         
##  [43] hash_2.2.6.3             rstudioapi_0.16.0        shinyAce_0.4.2          
##  [46] UCSC.utils_1.0.0         miniUI_0.1.1.1           generics_0.1.3          
##  [49] DOSE_3.30.5              base64enc_0.1-3          curl_5.2.3              
##  [52] zlibbioc_1.50.0          ggraph_2.2.1             polyclip_1.10-7         
##  [55] ca_0.71.1                GenomeInfoDbData_1.2.12  SparseArray_1.4.8       
##  [58] RBGL_1.80.0              threejs_0.3.3            desc_1.4.3              
##  [61] xtable_1.8-4             stringr_1.5.1            doParallel_1.0.17       
##  [64] evaluate_1.0.1           S4Arrays_1.4.1           BiocFileCache_2.12.0    
##  [67] hms_1.1.3                colorspace_2.1-1         filelock_1.0.3          
##  [70] NLP_0.3-0                shinyWidgets_0.8.7       magrittr_2.0.3          
##  [73] Rgraphviz_2.48.0         later_1.3.2              viridis_0.6.5           
##  [76] ggtree_3.12.0            lattice_0.22-6           NMF_0.28                
##  [79] genefilter_1.86.0        XML_3.99-0.17            shadowtext_0.1.4        
##  [82] cowplot_1.1.3            pillar_1.9.0             nlme_3.1-166            
##  [85] iterators_1.0.14         gridBase_0.4-7           caTools_1.18.3          
##  [88] compiler_4.4.0           stringi_1.8.4            shinycssloaders_1.1.0   
##  [91] Category_2.70.0          TSP_1.2-4                dendextend_1.18.1       
##  [94] GenomicAlignments_1.40.0 plyr_1.8.9               crayon_1.5.3            
##  [97] abind_1.4-8              BiocIO_1.14.0            gridGraphics_0.5-1      
## [100] emdbook_1.3.13           chron_2.3-61             locfit_1.5-9.10         
## [103] org.Hs.eg.db_3.19.1      graphlayouts_1.2.0       bit_4.5.0               
## [106] UpSetR_1.4.0             fastmatch_1.1-4          textshaping_0.4.0       
## [109] codetools_0.2-20         crosstalk_1.2.1          bslib_0.8.0             
## [112] slam_0.1-53              GetoptLong_1.0.5         tm_0.7-14               
## [115] plotly_4.10.4            mime_0.12                mosdef_1.1.3            
## [118] splines_4.4.0            markdown_1.13            circlize_0.4.16         
## [121] Rcpp_1.0.13              dbplyr_2.5.0             tippy_0.1.0             
## [124] cellranger_1.1.0         blob_1.2.4               utf8_1.2.4              
## [127] clue_0.3-65              fs_1.6.4                 pkgbuild_1.4.4          
## [130] backbone_2.1.4           IHW_1.32.0               expm_1.0-0              
## [133] ggplotify_0.1.2          sqldf_0.4-11             tibble_3.2.1            
## [136] Matrix_1.7-0             statmod_1.5.0            tweenr_2.0.3            
## [139] pkgconfig_2.0.3          pheatmap_1.0.12          tools_4.4.0             
## [142] cachem_1.1.0             RSQLite_2.3.7            numDeriv_2016.8-1.1     
## [145] viridisLite_0.4.2        DBI_1.2.3                fastmap_1.2.0           
## [148] rmarkdown_2.28           scales_1.3.0             grid_4.4.0              
## [151] shinydashboard_0.7.2     Rsamtools_2.20.0         sass_0.4.9              
## [154] coda_0.19-4.1            patchwork_1.3.0          BiocManager_1.30.25     
## [157] fontawesome_0.5.2        farver_2.1.2             tidygraph_1.3.1         
## [160] scatterpie_0.2.4         mgcv_1.9-1               gsubfn_0.7              
## [163] yaml_2.3.10              AnnotationForge_1.46.0   rtracklayer_1.64.0      
## [166] cli_3.6.3                purrr_1.0.2              txdbmaker_1.0.1         
## [169] webshot_0.5.5            lifecycle_1.0.4          mvtnorm_1.3-1           
## [172] sessioninfo_1.2.2        rintrojs_0.3.4           BiocParallel_1.38.0     
## [175] annotate_1.82.0          gtable_0.3.5             rjson_0.2.23            
## [178] ggridges_0.5.6           parallel_4.4.0           ape_5.8                 
## [181] limma_3.60.6             jsonlite_1.8.9           colourpicker_1.3.0      
## [184] seriation_1.5.6          bitops_1.0-9             ggplot2_3.5.1           
## [187] bit64_4.5.2              assertthat_0.2.1         brio_1.1.5              
## [190] yulab.utils_0.1.7        BiocNeighbors_1.22.0     proto_1.0.0             
## [193] heatmaply_1.5.0          geneLenDataBase_1.40.1   bs4Dash_2.3.4           
## [196] bdsmatrix_1.3-7          highr_0.11               jquerylib_0.1.4         
## [199] GOSemSim_2.30.2          R.utils_2.12.3           lazyeval_0.2.2          
## [202] dynamicTreeCut_1.63-1    htmltools_0.5.8.1        enrichplot_1.24.4       
## [205] rappdirs_0.3.3           STRINGdb_2.16.4          glue_1.8.0              
## [208] httr2_1.0.5              XVector_0.44.0           RCurl_1.98-1.16         
## [211] rprojroot_2.0.4          treeio_1.28.0            ComplexUpset_1.3.3      
## [214] gridExtra_2.3            igraph_2.0.3             R6_2.5.1                
## [217] tidyr_1.3.1              gplots_3.2.0             fdrtool_1.2.18          
## [220] labeling_0.4.3           GenomicFeatures_1.56.0   bbmle_1.0.25.1          
## [223] cluster_2.1.6            rngtools_1.5.2           pkgload_1.4.0           
## [226] aplot_0.2.3              plotrix_3.8-4            DelayedArray_0.30.1     
## [229] tidyselect_1.2.1         GOstats_2.70.0           ggforce_0.4.2           
## [232] xml2_1.3.6               munsell_0.5.1            KernSmooth_2.23-24      
## [235] goseq_1.56.0             data.table_1.16.2        htmlwidgets_1.6.4       
## [238] fgsea_1.30.0             ComplexHeatmap_2.20.0    RColorBrewer_1.1-3      
## [241] biomaRt_2.60.1           rlang_1.1.4              remotes_2.5.0           
## [244] rentrez_1.2.3            lpsymphony_1.32.0        Cairo_1.6-2             
## [247] fansi_1.0.6
LS0tCnRpdGxlOiAiWW91ciByZXBvcnQgZnJvbSBHZURpIgphdXRob3I6ICJgciBwYXN0ZTAoJ0dlRGkgcmVwb3J0ICh2JywgdXRpbHM6OnBhY2thZ2VWZXJzaW9uKCdHZURpJyksICcpJylgIgpkYXRlOiAiYHIgU3lzLkRhdGUoKWAiCgpvdXRwdXQ6IAogIGh0bWxfZG9jdW1lbnQ6CiAgICB0b2M6IHRydWUKICAgIHRvY19mbG9hdDogdHJ1ZQogICAgY29kZV9mb2xkaW5nOiBoaWRlCiAgICBjb2RlX2Rvd25sb2FkOiB0cnVlCiAgICBudW1iZXJfc2VjdGlvbnM6IHRydWUKICAgIGRmX3ByaW50OiBrYWJsZQogICAgdGhlbWU6IGx1bWVuCmFsd2F5c19hbGxvd19odG1sOiB5ZXMKLS0tCgpgYGB7ciBzZXR1cCwgaW5jbHVkZSA9IEZBTFNFfQprbml0cjo6b3B0c19jaHVuayRzZXQoCiAgZWNobyA9IFRSVUUsIAogIHdhcm5pbmcgPSBGQUxTRSwgCiAgbWVzc2FnZSA9IEZBTFNFLAogIGVycm9yID0gVFJVRQopCmBgYAoKCiMgSW50cm9kdWN0aW9uIC0gdGhlIGlucHV0IGRhdGEKSW4gdGhpcyBzZXNzaW9uIG9mIGBHZURpYCB5b3UgdXNlZCB0aGUgZm9sbG93aW5nIGRhdGE6CgpgYGB7ciBlY2hvID0gVFJVRX0KbGlicmFyeSgiR2VEaSIpCmBgYAoKCmBgYHtyIGlucHV0RGF0YX0KaWYoaXMubnVsbChyZWFjdGl2ZV92YWx1ZXMkZ2VuZXNldHMpKXsKICBjYXQoIkl0IHNlZW1zIGxpa2UgeW91IGRpZCBub3QgcHJvdmlkZSBkYXRhIGluIHRoaXMgc2Vzc2lvbi4iKQp9ZWxzZXsKICBEVDo6ZGF0YXRhYmxlKHJlYWN0aXZlX3ZhbHVlcyRnZW5lc2V0cywgY2FwdGlvbiA9ICJUaGUgaW5wdXQgZ2VuZXNldHMiKQp9CmBgYAoKRnJvbSB5b3VyIGluaXRpYWwgaW5wdXQgZGF0YSwgeW91IGhhdmUgZmlsdGVyZWQgdGhlIGZvbGxvd2luZyBnZW5lc2V0cwoKYGBge3IgZmlsdGVyZWR0RGF0YX0KaWYobGVuZ3RoKHJlYWN0aXZlX3ZhbHVlcyRmaWx0ZXJlZF9nZW5lc2V0cykgPiAwKXsKICBEVDo6ZGF0YXRhYmxlKHJlYWN0aXZlX3ZhbHVlcyRmaWx0ZXJlZF9nZW5lc2V0cywgY2FwdGlvbiA9ICJUaGUgZmlsdGVyZWQgZ2VuZXNldHMiKQp9ZWxzZXsKICBjYXQoIkl0IHNlZW1zIGxpa2UgeW91IGRpZG4ndCBmaWx0ZXIgZ2VuZXNldHMgZnJvbSB0aGUgaW5wdXQgZGF0YS4iKQp9CmBgYAoKUG90ZW50aWFsbHkgeW91IHNwZWNpZmllZCB0aGUgc3BlY2llcyBvZiB5b3VyIGRhdGEgYW5kIGRvd25sb2FkZWQgYSBQcm90ZWluLVByb3RlaW4tSW50ZXJhY3Rpb24gKFBQSSkgbWF0cml4LiAKCmBgYHtyIGlucHV0UFBJfQppZihpcy5udWxsKGlucHV0JHNwZWNpZXMpIHx8IGlucHV0JHNwZWNpZXMgPT0gIiIpewogIGNhdCgiSXQgc2VlbXMgbGlrZSB5b3UgZGlkbid0IHNwZWNpZnkgdGhlIHNwZWNpZXMgb2YgeW91ciBkYXRhLiIpCiAgCn1lbHNlewogY2F0KCJZb3Ugc3BlY2lmaWVkIHRoZSBzcGVjaWVzIG9mIHlvdXIgZGF0YSBhcyAiLCBpbnB1dCRzcGVjaWVzLCBzZXAgPSAiIikKfQoKaWYoIWlzLm51bGwocmVhY3RpdmVfdmFsdWVzJHBwaSkpewogIERUOjpkYXRhdGFibGUocmVhY3RpdmVfdmFsdWVzJHBwaSwgY2FwdGlvbiA9ICJUaGUgZG93bmxvYWRlZCBQUEkiKQp9ZWxzZXsKICBjYXQoIkl0IHNlZW1zIGxpa2UgeW91IGRpZCBub3QgZG93bmxvYWQgYSBQUEkgbWF0cml4LiIpCn0KYGBgCgoKIyMgUGFyYW1ldGVyIHNldHRpbmdzIAoKRm9yIHNvbWUgb2YgdGhlIGNhbGN1bGF0aW9ucyBhbmQgdmlzdWFsaXphdGlvbnMgb2YgdGhlIGFwcCwgdGhlIHNlbGVjdGVkIHBhcmFtZXRlcnMgYXJlIGltcG9ydGFudCBhbmQgY3J1Y2lhbCBmb3IgdGhlIHJlc3VsdHMuIFRoaXMgaXMgdGhlIGN1cnJlbnQgc3RhdGUgb2YgdGhlIGluZGl2aWR1YWwgcGFyYW1ldGVycy4KCmBgYHtyIHBhcmFtZXRlcnN9CmNhdCgiWW91ciBwYXJhbWV0ZXJzIG9mIHRoZSBEaXN0YW5jZSBTY29yZXMgcGFuZWwiKQoKc2NvcmVzIDwtIG5hbWVzKHJlYWN0aXZlX3ZhbHVlcyRzY29yZXMpCgppZihsZW5ndGgoc2NvcmVzKSA+IDApewogIHNjb3JpbmcgPC0gcGFzdGUoc2NvcmVzLCBjb2xsYXBzZSA9ICJcbiIpIAogIGNhdChwYXN0ZSgiWW91IGhhdmUgY2FsY3VsYXRlZCBkaXN0YW5jZSBzY29yZXMgb2YgeW91ciBkYXRhIHVzaW5nIHRoZSBmb2xsb3cgbWV0cmljczogXG4iLAogICAgICAgICAgICBzY29yaW5nLCBzZXAgPSAiIikpCiAgY2F0KHBhc3RlKCJcbkZvciB0aGUgY2x1c3RlcmluZyBtZXRob2QgaW4gdGhlIGRlbmRyb2dyYW0sIHlvdSBoYXZlIHNlbGVjdGVkICIsIGlucHV0JGNsdXN0ZXJfbWV0aG9kX2RlbmRybywgIi4iLCBzZXAgPSAiIikpCiAgY2F0KHBhc3RlKCJcbkFuZCBmb3IgdGhyZXNob2xkIGZvciB0aGUgU2NvcmluZyBOZXR3b3JrIHdhcyBzZXQgdG8gIiwgaW5wdXQkc2ltaWxhcml0eVNjb3JlcywgIi4iLCAgIHNlcCA9ICIiKSkKfWVsc2V7CiAgY2F0KCJJdCBzZWVtcyBsaWtlIHlvdSBkaWQgbm90IHNwZWNpZnkgYSBTY29yaW5nIG1ldGhvZCBhbmQgZGlkIG5vdCBzY29yZSB5b3VyIGRhdGEuIikKfQoKCmNhdCgiWW91ciBwYXJhbWV0ZXJzIG9mIHRoZSBDbHVzdGVyaW5nIEdyYXBoIHBhbmVsIikKCgpzdHJpbmcgPC0gcGFzdGUoIllvdSBoYXZlIHNlbGVjdGVkICIsIGlucHV0JHNlbGVjdF9jbHVzdGVyaW5nLCAiIGFzIGNsdXN0ZXJpbmcgbWV0aG9kLiBcbiIsIHNlcCA9ICIiKQppZihpcy5udWxsKGlucHV0JHNlbGVjdF9jbHVzdGVyaW5nKSl7CiAgc3RyaW5nIDwtICgiSXQgc2VlbXMgbGlrZSB5b3UgZGlkIG5vdCBjbHVzdGVyIHlvdXIgZGF0YSBpbiB0aGlzIHNlc3Npb24iKQp9ZWxzZSBpZihpbnB1dCRzZWxlY3RfY2x1c3RlcmluZyA9PSAiTG91dmFpbiIpewogIHN0cmluZyA8LSBwYXN0ZShzdHJpbmcsICJUaGUgdGhyZXNob2xkIHlvdSBzZWxlY3RlZCBmb3IgdGhlIExvdXZhaW4gY2x1c3RlcmluZyB3YXMgc2V0IHRvICIsIGlucHV0JGxvdXZhaW5fdGhyZXNob2xkICwgIi4iLCBzZXAgPSAiIikKfWVsc2UgaWYgKGlucHV0JHNlbGVjdF9jbHVzdGVyaW5nID09ICJNYXJrb3YiKXsKICBzdHJpbmcgPC0gcGFzdGUoc3RyaW5nLCAiVGhlIHRocmVzaG9sZCB5b3Ugc2VsZWN0ZWQgZm9yIHRoZSBNYXJrb3YgY2x1c3RlcmluZyB3YXMgc2V0IHRvICIsIGlucHV0JG1hcmtvdl90aHJlc2hvbGQgLCAiLiIsICBzZXAgPSAiIikKfWVsc2V7CiAgc3RyaW5nIDwtIHBhc3RlKCJUaGUgc2ltaWxhcml0eSBUaHJlc2hvbGQgd2FzIHNldCB0byAiLCBpbnB1dCRzaW1UaHJlc2hvbGQsICIuXG5UaGUgbWVtYmVyc2hpcCBUaHJlc2hvbGQgd2FzIHNldCB0byAiLCBpbnB1dCRtZW1UaHJlc2hvbGQsICIuIFxuVGhlIGNsdXN0ZXJpbmcgVGhyZXNob2xkIHdhcyBzZXQgdG8gIiwgaW5wdXQkY2x1c3RUaHJlc2hvbGQsICIuIiwgc2VwID0gIiIpCn0KY2F0KHN0cmluZykKYGBgCgojIEEgcXVpY2sgb3ZlcnZpZXcgb24gdGhlIHNjb3JpbmcgcmVzdWx0cwoKVGhpcyBzZWN0aW9uIHNob3dzIHRoZSB2aXN1YWxpemF0aW9ucyBvZiB0aGUgU2NvcmluZyBwYW5lbC4KCmBgYHtyIFNjb3JpbmdwYW5lbH0KaWYobGVuZ3RoKHJlYWN0aXZlX3ZhbHVlcyRzY29yZXMpID09IDApewogIGNhdCgiSXQgc2VlbXMgbGlrZSB5b3UgZG8gbm90IGhhdmUgZGlzdGFuY2Ugc2NvcmVzIGNhbGN1bGF0ZWQgZm9yIHlvdXIgZGF0YS4iKQp9ZWxzZXsKICBpZihpbnB1dCRwbG90c19kaXN0YW5jZV9zY29yZSA9PSAiIil7CiAgICBzY29yZXMgPC0gcmVhY3RpdmVfdmFsdWVzJHNjb3Jlc1tbMV1dIAogICAgY2F0KHBhc3RlKCJZb3VyIHBsb3RzIHdpbGwgYmUgZ2VuZXJhdGVkIG9uIHRoZSBkaXN0YW5jZSBzY29yZXMgY2FsY3VsYXRlZCB3aXRoICIsIG5hbWVzKHJlYWN0aXZlX3ZhbHVlcyRzY29yZXMpW1sxXV0sIHNlcCA9ICIiKSkKICB9ZWxzZXsKICAgIHNjb3JlcyA8LSByZWFjdGl2ZV92YWx1ZXMkc2NvcmVzW1tpbnB1dCRwbG90c19kaXN0YW5jZV9zY29yZV1dIAogICAgY2F0KHBhc3RlKCJZb3VyIHBsb3RzIHdpbGwgYmUgZ2VuZXJhdGVkIG9uIHRoZSBkaXN0YW5jZSBzY29yZXMgY2FsY3VsYXRlZCB3aXRoICIsIGlucHV0JHBsb3RzX2Rpc3RhbmNlX3Njb3JlLCBzZXAgPSAiIikpCiAgfQogIHNjb3JpbmdfaGVhdG1hcCA8LSBkaXN0YW5jZUhlYXRtYXAoc2NvcmVzKQogIHNjb3JpbmdfaGVhdG1hcAp9CmBgYAoKYGBge3IgZGVuZHJvfQppZighbGVuZ3RoKHJlYWN0aXZlX3ZhbHVlcyRzY29yZXMpID09IDApIHsKICBkZW5kcm8gPC0KICAgIGRpc3RhbmNlRGVuZHJvKHNjb3JlcywgaW5wdXQkY2x1c3Rlcl9tZXRob2RfZGVuZHJvKQogIGRlbmRybwp9IGVsc2V7CiAgY2F0KCJJdCBzZWVtcyBsaWtlIHlvdSBkbyBub3QgaGF2ZSBkaXN0YW5jZSBzY29yZXMgY2FsY3VsYXRlZCBmb3IgeW91ciBkYXRhLiIpCn0KYGBgCgpgYGB7ciBzY29yaW5nTmV0d29ya30KbGlicmFyeSgidmlzTmV0d29yayIpCmlmKCFsZW5ndGgocmVhY3RpdmVfdmFsdWVzJHNjb3JlcykgPT0gMCl7CiAgZ3JhcGggPC0gcmVhY3RpdmVfdmFsdWVzJHNjb3Jlc19ncmFwaCgpCgp2aXNOZXR3b3JrOjp2aXNJZ3JhcGgoZ3JhcGgpICU+JQogICAgICAgICAgdmlzTm9kZXMoY29sb3IgPSBsaXN0KAogICAgICAgICAgICBiYWNrZ3JvdW5kID0gIiMwMDkyQUMiLAogICAgICAgICAgICBoaWdobGlnaHQgPSAiZ29sZCIsCiAgICAgICAgICAgIGhvdmVyID0gImdvbGQiCiAgICAgICAgICApKSAlPiUKICAgICAgICAgIHZpc0VkZ2VzKGNvbG9yID0gbGlzdCgKICAgICAgICAgICAgYmFja2dyb3VuZCA9ICIjMDA5MkFDIiwKICAgICAgICAgICAgaGlnaGxpZ2h0ID0gImdvbGQiLAogICAgICAgICAgICBob3ZlciA9ICJnb2xkIgogICAgICAgICAgKSkgJT4lCiAgICAgICAgICB2aXNPcHRpb25zKAogICAgICAgICAgICBoaWdobGlnaHROZWFyZXN0ID0gbGlzdCgKICAgICAgICAgICAgICBlbmFibGVkID0gVFJVRSwKICAgICAgICAgICAgICBkZWdyZWUgPSAxLAogICAgICAgICAgICAgIGhvdmVyID0gVFJVRQogICAgICAgICAgICApLAogICAgICAgICAgICBub2Rlc0lkU2VsZWN0aW9uID0gVFJVRQogICAgICAgICAgKSAlPiUKICAgICAgICAgIHZpc0V4cG9ydCgKICAgICAgICAgICAgbmFtZSA9ICJkaXN0YW5jZV9zY29yZXNfbmV0d29yayIsCiAgICAgICAgICAgIHR5cGUgPSAicG5nIiwKICAgICAgICAgICAgbGFiZWwgPSAiU2F2ZSBEaXN0YW5jZSBTY29yZXMgZ3JhcGgiCiAgICAgICAgICApCn1lbHNlewogICAgY2F0KCJJdCBzZWVtcyBsaWtlIHlvdSBkbyBub3QgaGF2ZSBkaXN0YW5jZSBzY29yZXMgY2FsY3VsYXRlZCBmb3IgeW91ciBkYXRhLiIpCn0KYGBgCgoKIyBBIHF1aWNrIG92ZXJ2aWV3IG9mIHRoZSBjbHVzdGVyaW5nIHJlc3VsdHMKCmBgYHtyIGNsdXN0ZXJpbmdHcmFwaH0KaWYoIWlzLm51bGwocmVhY3RpdmVfdmFsdWVzJGNsdXN0ZXIpKXsKICBncmFwaCA8LSByZWFjdGl2ZV92YWx1ZXMkY2x1c3Rlcl9ncmFwaCgpCgp2aXNOZXR3b3JrOjp2aXNJZ3JhcGgoZ3JhcGgpICU+JQogICAgICAgICAgdmlzT3B0aW9ucygKICAgICAgICAgICAgaGlnaGxpZ2h0TmVhcmVzdCA9IGxpc3QoCiAgICAgICAgICAgICAgZW5hYmxlZCA9IFRSVUUsCiAgICAgICAgICAgICAgZGVncmVlID0gMSwKICAgICAgICAgICAgICBob3ZlciA9IFRSVUUKICAgICAgICAgICAgKSwKICAgICAgICAgICAgbm9kZXNJZFNlbGVjdGlvbiA9IFRSVUUsCiAgICAgICAgICAgIHNlbGVjdGVkQnkgPSBsaXN0KHZhcmlhYmxlID0gImNsdXN0ZXIiLCBtdWx0aXBsZSA9IFRSVUUpCiAgICAgICAgICApICU+JQogICAgICAgICAgdmlzRXhwb3J0KAogICAgICAgICAgICBuYW1lID0gImNsdXN0ZXJfbmV0d29yayIsCiAgICAgICAgICAgIHR5cGUgPSAicG5nIiwKICAgICAgICAgICAgbGFiZWwgPSAiU2F2ZSBDbHVzdGVyIGdyYXBoIgogICAgICAgICAgKQp9IGVsc2V7CiAgY2F0KCJJdCBzZWVtcyBsaWtlIHlvdSBkaWQgbm90IGNsdXN0ZXIgeW91ciBkYXRhIGluIHRoaXMgc2Vzc2lvbiIpCn0KYGBgCgpgYGB7ciBCaXBhcnRpdGVHcmFwaH0KaWYoIWlzLm51bGwocmVhY3RpdmVfdmFsdWVzJGNsdXN0ZXIpKXsKICBncmFwaCA8LSByZWFjdGl2ZV92YWx1ZXMkYmlwYXJ0aXRlX2dyYXBoKCkKCnZpc05ldHdvcms6OnZpc0lncmFwaChncmFwaCkgJT4lCiAgICAgICAgdmlzSWdyYXBoTGF5b3V0KGxheW91dCA9ICJsYXlvdXRfYXNfYmlwYXJ0aXRlIikgJT4lCiAgICAgICAgdmlzT3B0aW9ucygKICAgICAgICAgIGhpZ2hsaWdodE5lYXJlc3QgPSBsaXN0KAogICAgICAgICAgICBlbmFibGVkID0gVFJVRSwKICAgICAgICAgICAgZGVncmVlID0gMSwKICAgICAgICAgICAgaG92ZXIgPSBUUlVFCiAgICAgICAgICApLAogICAgICAgICAgbm9kZXNJZFNlbGVjdGlvbiA9IFRSVUUKICAgICAgICApICU+JQogICAgICAgIHZpc0V4cG9ydCgKICAgICAgICAgIG5hbWUgPSAiYmlwYXJ0aXRlX25ldHdvcmsiLAogICAgICAgICAgdHlwZSA9ICJwbmciLAogICAgICAgICAgbGFiZWwgPSAiU2F2ZSBDbHVzdGVyLUdlbmVzZXQgYmlwYXJ0aXRlIGdyYXBoIgogICAgICAgICkKfWVsc2V7CiAgY2F0KCJJdCBzZWVtcyBsaWtlIHlvdSBkaWQgbm90IGNsdXN0ZXIgeW91ciBkYXRhIGluIHRoaXMgc2Vzc2lvbiIpCn0KYGBgCgoKYGBge3IgZW5yaWNobWVudGNsb3VkLCBldmFsID0gRkFMU0UsIGVjaG8gPSBGQUxTRX0KaWYoIWlzLm51bGwocmVhY3RpdmVfdmFsdWVzJGNsdXN0ZXIpKXsKICAgICAgICBjbHVzdGVyIDwtIGFzLm51bWVyaWMoaW5wdXQkY2x1c3Rlcl9uYikKICAgICAgICBnZW5lc2V0cyA8LSByZWFjdGl2ZV92YWx1ZXMkY2x1c3RlcltbY2x1c3Rlcl1dCiAgICAgICAgZ2VuZXNldHNfZGYgPC0gcmVhY3RpdmVfdmFsdWVzJGdlbmVzZXRzW2dlbmVzZXRzLCBdCiAgICAgICAgZW5yaWNobWVudFdvcmRjbG91ZChnZW5lc2V0c19kZikKfWVsc2V7CiAgY2F0KCJJdCBzZWVtcyBsaWtlIHlvdSBkaWQgbm90IGNsdXN0ZXIgeW91ciBkYXRhIGluIHRoaXMgc2Vzc2lvbiIpCn0KYGBgCgojIEhpZ2hsaWdodGluZyB5b3VyIGJvb2ttYXJrZWQgZ2VuZXNldHMgYW5kIGNsdXN0ZXJzCgpJZiB5b3UgaGF2ZSBib29rbWFya2VkIGFueSBnZW5lc2V0cyBvciBjbHVzdGVycywgdGhleSB3aWxsIGJlIGRpc3BsYXllZCBoZXJlLgoKYGBge3IgYm9va21hcmtlZEdlbmVzZXRzfQppZighKG5yb3cocmVhY3RpdmVfdmFsdWVzJGJvb2ttYXJrZWRfZ2VuZXNldHMpID09IDApKXsKICBjYXQoIkhlcmUgaXMgYSBkYXRhIHRhYmxlIG9mIHlvdXIgYm9va21hcmtlZCBnZW5lc2V0cy4gXG4iKQogIERUOjpkYXRhdGFibGUocmVhY3RpdmVfdmFsdWVzJGJvb2ttYXJrZWRfZ2VuZXNldHMsIHJvd25hbWVzID0gRikKfWVsc2V7CiAgY2F0KCJZb3UgaGF2ZSBub3QgYm9va21hcmtlZCBhbnkgZ2VuZXNldHMgdG8gYmUgZGlzcGxheWVkIGhlcmUuIikKfQpgYGAKCgpgYGB7ciBib29rbWFya2VkQ2x1c3RlcnN9CmlmKCEobnJvdyhyZWFjdGl2ZV92YWx1ZXMkYm9va21hcmtlZF9jbHVzdGVyKSA9PSAwKSl7CiAgZm9yKGkgaW4gMTpucm93KHJlYWN0aXZlX3ZhbHVlcyRib29rbWFya2VkX2NsdXN0ZXIpKXsKICAgIGNsdXN0ZXIgPC0gcmVhY3RpdmVfdmFsdWVzJGJvb2ttYXJrZWRfY2x1c3RlcltpLCBdCiAgICBjbHVzdGVyX25iIDwtIGNsdXN0ZXJbWyJDbHVzdGVyIl1dCiAgICBjYXQocGFzdGUoIk5vdywgd2Ugd2lsbCBoYXZlIGEgbG9vayBhdCAiLCBjbHVzdGVyX25iLCAiIHdoaWNoIGhhcyB0aGUgZm9sbG93aW5nIGdlbmVzZXRzIGFzIG1lbWJlcnM6ICIsIGNsdXN0ZXJbIkNsdXN0ZXJfTWVtYmVycyJdLCAiLlxuIiwgc2VwID0gIiIpKQogICAgY2F0KHBhc3RlKCJUaGUgY2x1c3RlcnMgYXJlIGludm9sdmVkIGluIHRoZSBmb2xsb3dpbmcgYmlvbG9naWNhbCBwcm9jZXNzZXM6ICIsIGNsdXN0ZXJbIkNsdXN0ZXJfTWVtYmVyX0Rlc2NyaXB0aW9uIl0sICIuXG4iLCBzZXAgPSAiIikpCgogICAgY2x1c3Rlcl9uYiA8LSBhcy5udW1lcmljKHVubGlzdChzdHJzcGxpdCgKICAgICAgICBjbHVzdGVyX25iLCBzcGxpdCA9ICcgJywgZml4ZWQgPSBUUlVFCiAgICAgICkpWzJdKQogICAgCiAgICBnZW5lc2V0cyA8LSByZWFjdGl2ZV92YWx1ZXMkY2x1c3RlcltbY2x1c3Rlcl9uYl1dCiAgICBnZW5lc2V0c19kZiA8LSByZWFjdGl2ZV92YWx1ZXMkZ2VuZXNldHNbZ2VuZXNldHMsIF0KICAgIGNhdChwYXN0ZSgiU2hvd2luZyB0aGUgRW5yaWNobWVudCBXb3JkY2xvdWQgZm9yIGNsdXN0ZXIgIiwgY2x1c3Rlcl9uYiwgIlxuXG4iLCBzZXAgPSAiIikpCiAgICBlIDwtIGVucmljaG1lbnRXb3JkY2xvdWQoZ2VuZXNldHNfZGYpCiAgICBwcmludChlKQogICAgICAKICB9Cn1lbHNlewogIGNhdCgiWW91IGhhdmUgbm90IGJvb2ttYXJrZWQgYW55IGNsdXN0ZXJzIHRvIGJlIGRpc3BsYXllZCBoZXJlLiIpCn0KYGBgCgoKIyBBYm91dCB0aGlzIHJlcG9ydAoKSWYgeW91IHVzZSB0aGlzIHJlcG9ydCBpbiB5b3VyIHNjaWVudGlmaWMgd29yaywgcGxlYXNlIGNpdGUgR2VEaToKCmBgYHtyLCBldmFsID0gRkFMU0V9CnV0aWxzOjpjaXRhdGlvbigiR2VEaSIpCmBgYAoKCiMgU2Vzc2lvbiBpbmZvIHstfQoKVGhpcyBpcyB0aGUgb3V0cHV0IG9mIHRoZSBgc2Vzc2lvbkluZm8oKWAgY29tbWFuZCwgcmVwb3J0ZWQgZm9yIGltcHJvdmluZyB0aGUgcmVwcm9kdWNpYmlsaXR5IG9mIHRoZSBhbmFseXNpcy4KCmBgYHtyfQp1dGlsczo6c2Vzc2lvbkluZm8oKQpgYGAKCg==